package com.edu.employee.service.impl;

import com.edu.commons.*;
import com.edu.employee.mapper.EmpMapper;
import com.edu.employee.pojo.dto.EmpInfoDTO;
import com.edu.employee.pojo.dto.EmpLoginDTO;
import com.edu.employee.pojo.dto.EmpQueryDTO;
import com.edu.employee.pojo.dto.EmpUpdatePwdDTO;
import com.edu.employee.pojo.entity.*;
import com.edu.employee.pojo.vo.EmpInfoUpdateVO;
import com.edu.employee.pojo.vo.EmpInfoVO;
import com.edu.employee.pojo.vo.EmpListVO;
import com.edu.employee.pojo.vo.EmpLoginVO;
import com.edu.employee.service.EmpService;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

/**
 * @ProjectName: summer-project
 * @Titile: EmpServiceImpl
 * @Author: Lucky
 * @Description: 员工业务实现类
 */
@Service //业务注解 具有语义化
@Transactional //事务注解
public class EmpServiceImpl implements EmpService {
    private static final Logger log = LoggerFactory.getLogger(EmpServiceImpl.class);
    //注入持久层
    @Autowired
    private EmpMapper empMapper;
    /*头像保存的目录*/
    @Value("${avatar.path}") //要具有setter方法，才能注入
    @Setter //setter注入
    private String saveDir;
    @Override
    public EmpLoginVO login(EmpLoginDTO empLoginDTO) {
        //调用持久层对象：根据员工账户查询员工信息
        Employee emp = empMapper.getEmpByAccount(empLoginDTO.getAccount());
        //判断该员工是否存在
        if(emp==null){
            throw new ServiceException(ServiceCode.ERROR_LOGIN_FAIL,"员工的账户不存在");
        }
        // emp就不为空了
        //判断密码
        //1.取出盐值
        String salt = emp.getSalt();
        //2.取出数据库中的密码:这个密码是加了密的
        String password = emp.getPassword();
        //3.将登录的密码进行加密
        String loginPwd = MD5Utils.encrypt(empLoginDTO.getPassword(), salt, Constants.HASH_TIME);
        //4.判断密码
        if(!password.equals(loginPwd)){
            throw new ServiceException(ServiceCode.ERROR_LOGIN_FAIL,"密码不正确");
        }
        //代码执行到这里：密码是正确的
        //判断员工的状态
        if(emp.getStatusId() == Constants.EMP_LEAVE_STATUS){
            throw new ServiceException(ServiceCode.ERROR_EMP_LEAVE,"该员工已经离职");
        }
        if(emp.getStatusId()== Constants.EMP_DISABLED_STATUS){
            throw new ServiceException(ServiceCode.ERROR_EMP_DISABLED,"该账户被禁用");
        }
        //经过了完整的验证,需要封装返回的数据
        EmpLoginVO empLoginVO = new EmpLoginVO();
        empLoginVO.setEmpName(emp.getEmpName());

        // 生成token
        EmpVO empVO = new EmpVO();
        empVO.setEmpId(emp.getEmpId());
        empVO.setEmpName(emp.getEmpName());
        String token = JWTUtils.generateToken(empVO);
        //把token封装到返回的数据对象中
        empLoginVO.setToken(token);
        //设置头像
        if(emp.getAvatar().isEmpty()){
            empLoginVO.setAvatar(emp.getAvatar());
        }else{
            String avatar = "/avatar/"+emp.getAvatar()+"?token="+token;
            empLoginVO.setAvatar(avatar);
        }
        return empLoginVO;
    }

    @Override
    public void updatePwd(EmpUpdatePwdDTO updatePwdDTO, EmpVO empVO) {
        //判断新密码与原密码是否一致
        if(updatePwdDTO.getOldPassword().equals(updatePwdDTO.getNewPassword())){
            throw new ServiceException(ServiceCode.ERROR,"新密码不能与原密码相同");
        }
        //判断新密码与确认密码要一致
        if(!updatePwdDTO.getNewPassword().equals(updatePwdDTO.getReNewPassword())){
            throw new ServiceException(ServiceCode.ERROR,"确认密码与新密码不一致");
        }
        //判断原密码是否正确:通过员工编号去查询员工信息
        Employee emp = empMapper.getEmpById(empVO.getEmpId());
        if(emp==null || emp.getEmpId()==null){
            throw new ServiceException(ServiceCode.ERROR_DATA_NOT_FOUND,"该员工不存在");
        }
        //对原密码进行加密：从前端传递过来的原密码
        String password = MD5Utils.encrypt(updatePwdDTO.getOldPassword(), emp.getSalt(), Constants.HASH_TIME);
        //判断原密码是否正确
        if(!password.equals(emp.getPassword())){
            throw new ServiceException(ServiceCode.ERROR_LOGIN_FAIL,"原密码错误");
        }
        //获取盐值
        String salt = UUID.randomUUID().toString().replace("-","");
        //对新密码进行加密
        String newPassword = MD5Utils.encrypt(updatePwdDTO.getNewPassword(),salt,Constants.HASH_TIME);
        //创建一个员工对象与封装员工的密码和员工编号
        Employee employee = new Employee();
        //新密码
        employee.setPassword(newPassword);
        //新的盐值
        employee.setSalt(salt);
        //修改条件
        employee.setEmpId(empVO.getEmpId());
        //调用持久层方法修改密码
        int result =  empMapper.updatePwd(employee);
        if(result != 1){
            throw new ServiceException(ServiceCode.ERROR_UPDATE_FAIL,"修改密码失败");
        }
    }

    @Override
    public EmpInfoVO getEmpInfo(EmpVO empVO) {
        //根据员工的编号查询员工的个人信息
        EmpInfoVO empInfoVO =  empMapper.getEmpInfoById(empVO.getEmpId());
        if(empInfoVO==null || empInfoVO.getEmpName().isEmpty()){
            throw  new ServiceException(ServiceCode.ERROR_DATA_NOT_FOUND,"没有查询到该员工的信息");
        }
        if(empInfoVO.getAvatar()!=null && !empInfoVO.getAvatar().isEmpty()){
            empInfoVO.setAvatar("/avatar/"+empInfoVO.getAvatar()+"?token="+JWTUtils.generateToken(empVO));
        }
        return empInfoVO;
    }

    @Override
    public List<EmpStatus> getEmpStatusList() {
        List<EmpStatus> empStatusList =  empMapper.getEmpStatusList();
        if(empStatusList==null ||empStatusList.isEmpty()){
            throw new ServiceException(ServiceCode.ERROR_DATA_NOT_FOUND,"没有员工状态列表数据");
        }
        return empStatusList;
    }

    @Override
    public List<Marriage> getMarriageList() {
        List<Marriage> marriageList = empMapper.getMarriageList();
        if(marriageList==null || marriageList.isEmpty()){
            throw new ServiceException(ServiceCode.ERROR_DATA_NOT_FOUND,"没有婚姻状况列表数据");
        }
        return marriageList;
    }

    @Override
    public List<MinZu> getMinZuList() {
        List<MinZu> minZuList = empMapper.getMinZuList();
        if(minZuList==null || minZuList.isEmpty()){
            throw new ServiceException(ServiceCode.ERROR_DATA_NOT_FOUND,"没有民族列表数据");
        }
        return minZuList;
    }

    @Override
    public List<Certificates> getTypeList() {
        List<Certificates> certificatesList = empMapper.getTypeList();
        if(certificatesList==null || certificatesList.isEmpty()){
            throw new ServiceException(ServiceCode.ERROR_DATA_NOT_FOUND,"没有证件类型列表数据");
        }
        return certificatesList;
    }

    @Override
    public EmpInfoUpdateVO updateEmpInfo(EmpInfoDTO empInfoDTO, EmpVO empVO) {
        //1.检查证件类型编号是否符合要求
        Certificates certificates = empMapper.getTypeById(empInfoDTO.getTypeId());
        if(certificates==null || certificates.getTypeName().isEmpty()){
            throw new ServiceException(ServiceCode.ERROR_BAD_REQUEST,"证件类型编号错误");
        }
        //2.检查民族编号
        MinZu minZu = empMapper.getMinZuById(empInfoDTO.getMinZuId());
        if(minZu==null || minZu.getMinZuName().isEmpty()){
            throw new ServiceException(ServiceCode.ERROR_BAD_REQUEST,"民族编号错误");
        }
        //3.检查婚姻状况
        Marriage marriage = empMapper.getMarriageById(empInfoDTO.getMarriageId());
        if(marriage==null || marriage.getMarriageInfo().isEmpty()){
            throw new ServiceException(ServiceCode.ERROR_BAD_REQUEST,"婚姻状况编号错误");
        }
        //初始化文件名
        String filename = null;
        //判断这个头像是否为空
        if(empInfoDTO.getAvatar()!=null && !empInfoDTO.getAvatar().isEmpty()){
            //获取头像
            MultipartFile avatar = empInfoDTO.getAvatar();
            //获取文件名
            filename = avatar.getOriginalFilename();
            //使用uuid作为文件的名称
            filename=UUID.randomUUID().toString().replace("-","")+filename.substring(filename.lastIndexOf("."));
            log.debug("上传的文件名称:{}",filename);
            //进行文件上传
            //保证这个存储头像的目录已存在
            File parentFile = new File(saveDir);
            if(!parentFile.exists()){
                parentFile.mkdirs();//递归创建目录
            }
            try {
                //上传文件
                avatar.transferTo(new File(parentFile,filename));
            } catch (IOException e) {
                filename = null;
                log.debug("文件上传失败:{}",e.getMessage());
                throw new ServiceException(ServiceCode.ERROR_FILE_UPLOAD_FAIL,"文件上传失败");
            }
        }
        //封装一个员工对象来装修改的数据
        Employee employee = new Employee();
        employee.setEmpName(empInfoDTO.getEmpName());
        employee.setEmpId(empVO.getEmpId());//条件，这里只能修改自己
        employee.setEmpPost(empInfoDTO.getEmpPost());
        employee.setEmpProfile(empInfoDTO.getEmpProfile());
        employee.setGender(empInfoDTO.getGender());
        employee.setPhone(empInfoDTO.getPhone());
        employee.setMarriageId(empInfoDTO.getMarriageId());
        employee.setMinZuId(empInfoDTO.getMinZuId());
        employee.setTypeId(empInfoDTO.getTypeId());
        employee.setTypeCode(empInfoDTO.getTypeCode());
        employee.setAddress(empInfoDTO.getAddress());
        employee.setDeptId(empInfoDTO.getDeptId());
        employee.setEmpProfile(empInfoDTO.getEmpProfile());
        //头像如何设置：数据库保存头像的名称
        employee.setAvatar(filename);
        //修改操作
        int result =  empMapper.updateEmpInfo(employee);
        if(result != 1){
            throw  new ServiceException(ServiceCode.ERROR_UPDATE_FAIL,"修改个人信息失败");
        }
        //封装返回值
        EmpInfoUpdateVO empInfoUpdateVO = new EmpInfoUpdateVO();
        empInfoUpdateVO.setEmpName(employee.getEmpName());
        empInfoUpdateVO.setAvatar(filename);
        return empInfoUpdateVO;
    }

    @Override
    public PageVO<EmpListVO> getEmpList(EmpQueryDTO empQueryDTO) {
        //获取页码值
        Integer pageNum = empQueryDTO.getPageNum();
        //判断页码是否为null
        if(pageNum==null || pageNum < 1){
            pageNum = 1;
        }
        //获取每页显示的数据量
        Integer pageSize = empQueryDTO.getPageSize();
        if(pageSize == null || pageSize < 1){
            //默认显示10条
            pageSize = Constants.DEFAULT_PAGE_SIZE;
        }
        //分页查询的参数设置
        /*这行代码一定要放在查询的前面，分页才会生效：采用的是拦截器的原理实现的功能*/
        PageHelper.startPage(pageNum,pageSize);
        //调用持久层那对象的方法进行查询,得到结果后进行强转
        Page<EmpListVO> empList = (Page<EmpListVO>) empMapper.getEmpList(empQueryDTO);
        if(empList.isEmpty()){
            throw new ServiceException(ServiceCode.ERROR_DATA_NOT_FOUND,"没有查询到数据");
        }
        //封装返回的数据
        PageVO<EmpListVO> pageVO = new PageVO<>();
        //页码
        pageVO.setPageNum(empList.getPageNum());
        //总数据量
        pageVO.setTotal(empList.getTotal());
        //每页显示数据量
        pageVO.setPageSize(empList.getPageSize());
        //总页码
        pageVO.setPages(empList.getPages());
        //数据列表
        pageVO.setPageDataList(empList);
        return pageVO;
    }
}
